package com.zhny.aiot.plugin.HeadControlBoxPlugin;

import com.google.common.collect.ImmutableMap;
import com.zhny.aiot.plugin.HeadControlBoxPlugin.model.*;
import com.zhny.aiot.plugin.ICenterFacilities;
import com.zhny.aiot.plugin.IDeviceFactory;
import com.zhny.aiot.plugin.core.utils.MessageUtils;
import com.zhny.aiot.plugin.model.DeviceEntity;
import com.zhny.aiot.plugin.model.MessageEntry;
import com.zhny.aiot.plugin.model.MessageType;
import com.zhny.aiot.plugin.model.TaskEntity;
import com.zhny.aiot.plugin.zhnygateway.GatewayEngine;
import com.zhny.aiot.plugin.zhnygateway.device.ZhnyConfig;
import com.zhny.aiot.plugin.zhnygateway.device.ZhnyDevice;
import com.zhny.aiot.plugin.zhnygateway.model.GatewayResponseMessage;
import com.zhny.aiot.plugin.zhnygateway.model.NodeRequestMessage;

import java.util.Map;

/**
 * @author pengshuai
 * @date 2023-03-23 13:45
 */
public class HeadControlBoxDevice extends ZhnyDevice<HeadControlBoxStoreEntity> {

    private final Map<String, Integer> CommandOperations;

    public HeadControlBoxDevice(GatewayEngine engine, IDeviceFactory<ZhnyConfig> factory, ICenterFacilities centerFacilities, DeviceEntity entity) {
        super(engine, factory, centerFacilities, entity);
        CommandOperations = new ImmutableMap.Builder<String,Integer>()
                .put("open1",0x01)
                .put("close1",0x02)
                .put("open2",0x03)
                .put("close2",0x04)
                .put("open3",0x05)
                .put("close3",0x06)
                .put("open4",0x09)
                .put("close4",0x0a)
                .put("open5",0x16)
                .put("close5",0x17)
                .put("check",0x0d)
                .build();
    }

    @Override
    public void onDecoder(GatewayResponseMessage message) {
        MessageEntry resultMsg = MessageUtils.createMessageEntry(this.getId());
        resultMsg.setType(MessageType.RESULT);
        HeadControlBoxStoreEntity storeEntry = new HeadControlBoxStoreEntity();
        int operation = message.getDeviceOper();
        int dataLength = message.getDataLength();
        if(dataLength != 0x05 && dataLength != 0x0e){
            resultMsg.setType(MessageType.ERROR);
            resultMsg.setData("水泵加入任务异常，由于数据长度不匹配。");
            logger.error("[deviceNo:{},controllerNo:{}] 水泵加入任务[{}]失败",getConfig().getAddress(),getConfig().getChannelNo(),operation);
            nofity(resultMsg);
        }else{
            if(operation == 0x01){
                storeEntry.setAccess1(true);
                resultMsg.setData(storeEntry);
            }
            else if( operation == 0x02){
                storeEntry.setAccess1(false);
                resultMsg.setData(storeEntry);
            }else if(operation == 0x03){
                storeEntry.setAccess2(true);
                resultMsg.setData(storeEntry);
            }
            else if( operation == 0x04){
                storeEntry.setAccess2(false);
                resultMsg.setData(storeEntry);
            }else if(operation == 0x05){
                storeEntry.setAccess3(true);
                resultMsg.setData(storeEntry);
            }
            else if(operation == 0x06){
                storeEntry.setAccess3(false);
                resultMsg.setData(storeEntry);
            }else if(operation == 0x09){
                storeEntry.setAccess4(true);
                resultMsg.setData(storeEntry);
            }
            else if( operation == 0x0a){
                storeEntry.setAccess4(false);
                resultMsg.setData(storeEntry);
            }else if(operation == 0x16){
                storeEntry.setAccess5(true);
                resultMsg.setData(storeEntry);
            }
            else if( operation == 0x17){
                storeEntry.setAccess5(false);
                resultMsg.setData(storeEntry);
            }else if(operation == 0x0d){
                storeEntry.setAccess1(message.getDeviceData ().readUnsignedByte ()==1?true:false);
                storeEntry.setAccess2(message.getDeviceData ().readUnsignedByte ()==1?true:false);
                storeEntry.setAccess3(message.getDeviceData ().readUnsignedByte ()==1?true:false);
                storeEntry.setAccess4(message.getDeviceData ().readUnsignedByte ()==1?true:false);
                storeEntry.setAccess5(message.getDeviceData ().readUnsignedByte ()==1?true:false);
                resultMsg.setData(storeEntry);
            }
            logger.info("device name[{}],store[{}]",this.entity.getName(),storeEntry.toString());
            save(storeEntry);
            saveReal(storeEntry);
            nofity(resultMsg);
        }
    }

    @Override
    protected NodeRequestMessage onCommand(TaskEntity task) {
        String taskName = task.getMethodName();
        if(taskName.isEmpty() || !CommandOperations.containsKey(taskName)) {
            return null;
        }else if(taskName.equals("check")){
            Integer operate = CommandOperations.get("check");
            return new NodeRequestMessage(getzhnyType()+ 128,4,operate, Integer.parseInt(getConfig().getAddress()),null);
        }else{
            Integer operate = CommandOperations.get(taskName);
            byte[] data = new byte[]{0x00,0x00};
            return new NodeRequestMessage(getzhnyType() + 128 ,data.length + 4 ,operate, Integer.parseInt(getConfig().getAddress()),data);
        }
    }

    @Override
    protected int getzhnyType() {
        return 4;
    }

    @Override
    protected void disposable() {

    }
}
